package com.ledim.activity.base;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import com.ledim.adapter.base.LedimBaseListAdapter;
import com.ledim.widget.loadmore.LoadMoreListViewContainer;
import com.letv.android.young.client.R;
import com.ledim.utils.ConstantUtil;
import com.ledim.utils.LedimNetWorkUtils;
import com.ledim.widget.loadmore.LoadMoreStateCode;
import com.ledim.widget.ptr.LedimListViewStateView;
import com.ledim.widget.ptr.PtrClassicFrameLayout;
import com.ledim.widget.ptr.PtrDefaultHandler;
import com.ledim.widget.ptr.PtrFrameLayout;
import com.ledim.widget.ptr.PtrHandler;
import com.ledim.widget.ptr.header.LedimListViewHeader;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by ccx on 16/05/18.
 * 这里使用的LoadMoreStateCode和loadmorecontainer中的完全一致，可以直接使用
 *
 * @param <D>
 *         数据源
 * @param <L>
 */
public abstract class LedimBaseAdapterViewActivity<D, L extends AbsListView>
        extends LeDimBaseActivity implements LoadMoreStateCode {

    protected int mTotalPages = 0;// 总页数
    protected int mCurrPage = 0;// 当前页
    protected int mLoadPage = 0;// loading的页

    protected LoadMoreListViewContainer loadMoreContainer;

    /**
     * 刷新还是加载更多 true： 刷新 ，false：上拉加载
     */
    protected boolean isRefresh = true;

    protected L mAdapterView;
    /**
     * 下拉刷新控件
     */
    protected PtrClassicFrameLayout mRefreshView;

    /**
     * 各种状态的view，包括loading,server_error,no_net,no_data
     */
    protected LedimListViewStateView mLedimStateView;
    protected List<D> mItems = new ArrayList<D>();
    protected LedimBaseListAdapter<D> mAdapter;
    /**
     * TYPE_PULL_REFRESH 下拉刷新
     * TYPE_CLICK_STATEVIEW_REFRESH 点击中间stateview刷新
     */
    protected final static int TYPE_PULL_REFRESH = 0;
    protected final static int TYPE_CLICK_STATEVIEW_REFRESH = TYPE_PULL_REFRESH + 1;


    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapterView = initAdapterView();
        mAdapter = getAdapter();
        initFooterView();
        if (loadMoreContainer != null && enableLoadMoreRefresh()) {
            mAdapter.setOnScrollListener(loadMoreContainer);
        }
        mAdapterView.setAdapter(mAdapter);
        mAdapterView.setOnScrollListener(mAdapter);
        // 这里直接关联adapter与list, 刷新无需再调用adapter的 setDatas,只调用notify即可
        mAdapter.setInfos(mItems);

        mRefreshView = initRefreshView();
        mLedimStateView = (LedimListViewStateView) findViewById(R.id.state_view);
        mLedimStateView.setOnRetryListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                refresh(TYPE_CLICK_STATEVIEW_REFRESH);
                // autoRefresh();
            }
        });
        mLedimStateView.setNoDataText(getNoDataStateTextId());

        // 第一次进来时自动刷新
        if (enterAutoLoadData()) {
            refresh(TYPE_CLICK_STATEVIEW_REFRESH);
        }
        // 如果使用ptr的autorefresh，不要直接调，建议postdelayed。
        // mHandler.postDelayed(new Runnable()
        // {
        // @Override
        // public void run()
        // { // 直接回调onRefreshBegin
        // autoRefresh();
        //
        // }
        // }, 100);
    }

    public int getNoDataStateTextId() {
        return 0;
    }
    /**
     * @return 是否进入首页页面加载数据
     */
    protected boolean enterAutoLoadData() {
        return true;
    }

    /**
     * 下拉刷新
     */
    protected void pullRefresh() {
        refresh(TYPE_PULL_REFRESH);
    }

    protected abstract LedimBaseListAdapter<D> getAdapter();

    // protected abstract L initAdapterView();

    protected L initAdapterView() {
        return findViewByIdExt(R.id.list);
    }

    /**
     * 发送请求，在这里调用mDataUtil的请求网络（推荐使用retri+okhttp在成功回调中调用setDatas方法）
     */
    protected abstract void getDatas();

    /**
     * 子类自定义的部分
     */
    protected void initFooterView() {
    }

    protected void autoRefresh() {
        mRefreshView.autoRefresh(true);
    }

    protected final int getTotalPages(int totalNum) {
        if (totalNum <= getPageSize()) {
            return 1;
        }
        return totalNum % getPageSize() == 0 ? (totalNum / getPageSize())
                                             : (totalNum / getPageSize() + 1);
    }

    /**
     * 加载更多方法，有更多数据时才能调用
     */
    protected void loadMore() {
        isRefresh = false;
        // 如果loadmore的时候失败，但是mCurrPage已经++了
        mLoadPage++;
        getDatas();
    }

    /**
     * 仅仅是不使用hasmore字段的判断
     *
     * @return
     */
    private boolean hasMoreData() {
        return mLoadPage < mTotalPages;
    }

    /**
     * 刷新方法
     *
     * @param refreshType
     *         刷新类型
     *         下拉刷新 or 点击stateview刷新
     */
    protected void refresh(int refreshType) {
        isRefresh = true;
        mLoadPage = 0;
        mCurrPage = 0;
        mAdapterView.setSelection(0);
        if (refreshType == TYPE_PULL_REFRESH) {
            mLedimStateView.setState(LedimListViewStateView.STATE_OTHER);
        } else {
            mLedimStateView.setState(LedimListViewStateView.STATE_LOADING);
        }
        getDatas();
    }

    protected List<D> getItems() {
        return mItems;
    }

    /**
     * 服务器返回数据未成功
     */
    protected void setServerDataError() {
        if (isRefresh) {
            mItems.clear();
            if (enablePullRefresh() && mRefreshView.isRefreshing()) { // ptr的刷新
                mRefreshView.refreshComplete();
            } else {
                loadingClose();
            }
        }
        if (isRefresh) {
            if (!LedimNetWorkUtils.isNetworkAvailable(this)) {
                mLedimStateView.setState(LedimListViewStateView.STATE_NO_NET);
            } else {
                mLedimStateView.setState(LedimListViewStateView.STATE_SERVER_ERROR);
            }
            loadMoreFinish(STATE_REFRESH, false);
        } else { // 加载更多，证明已经有数据了，并不清空已有数据，不设置error状态
            mLoadPage = mCurrPage;
            // 如果loadmore的时候服务器拿不到数据，就认为hasMore=true
            loadMoreFinish(LedimNetWorkUtils.isNetworkAvailable(this) ? ERROR_SE
                                                                      : ERROR_NET, hasMoreData());
            mLedimStateView.setState(LedimListViewStateView.STATE_NORMAL);
        }

        mAdapter.notifyDataSetChanged();
    }

    /**
     * 如果使用服务器hasmore字段，就必须调用这个方法（推荐使用如果可以）
     *
     * @param list
     *         当数据异常得到的list为null时，setDatas(null)即可
     * @param hasMore
     *         是否有更多（来自服务器的字段）
     */
    protected void setDatas(List<D> list, boolean hasMore) {
        if (isRefresh) {
            mItems.clear();
            if (enablePullRefresh() && mRefreshView.isRefreshing()) { // ptr的刷新
                mRefreshView.refreshComplete();
            } else {
                loadingClose();
            }
        }
        if (list == null || list.isEmpty()) {
            if (isRefresh) {
                if (!LedimNetWorkUtils.isNetworkAvailable(this)) {
                    mLedimStateView.setState(LedimListViewStateView.STATE_NO_NET);
                } else {
                    mLedimStateView.setState(LedimListViewStateView.STATE_NO_DATA);
                }
                loadMoreFinish(STATE_REFRESH, false);
            } else { // 加载更多，证明已经有数据了，并不清空已有数据，不设置error状态
                mLoadPage = mCurrPage;
                // 如果loadmore的时候服务器拿不到数据，就认为hasMore=true
                loadMoreFinish(
                        LedimNetWorkUtils.isNetworkAvailable(this) ? ERROR_SE : ERROR_NET, true);
                mLedimStateView.setState(LedimListViewStateView.STATE_NORMAL);
            }

        } else {
            mLedimStateView.setState(LedimListViewStateView.STATE_NORMAL);
            mItems.addAll(list);
            if (!isRefresh) {
                mCurrPage++;
            }
            loadMoreFinish(STATE_NORMAL, hasMore);
        }
        mAdapter.notifyDataSetChanged();
    }

    /**
     * @param errorCode
     *         -1表示unkonw错误，0表示正常，1表示网络异常，2表示服务器异常，等
     * @param hasMore
     */
    protected abstract void loadMoreFinish(int errorCode, boolean hasMore);

    /**
     * 使用loading 进行刷新，需要在结束后手动关闭
     */
    protected void loadingClose() {
        mLedimStateView.setState(LedimListViewStateView.STATE_NORMAL);
    }

    /**
     * @param totalPage
     */
    protected void setTotalPages(int totalPage) {
        mTotalPages = totalPage;
    }

    protected void initTotalPages(int totalNum) {
        mTotalPages = getTotalPages(totalNum);
    }

    protected int getPageSize() {
        return ConstantUtil.PAGE_SIZE;
    }

    protected final int getCurrPage() {
        return mCurrPage;
    }

    protected final int getLoadOffset() {
        return mLoadPage * getPageSize();
    }

    protected PtrClassicFrameLayout initRefreshView() {
        PtrClassicFrameLayout ptr = (PtrClassicFrameLayout) findViewById(R.id.ptr_view);
        // 以下设置大都可在xml中设置
        // 设置阻尼系数
        // ptr.setResistance(1.7f);
        // // 触发刷新时移动的位置比例，默认，1.2f，移动达到头部高度 1.2 倍时可触发刷新操作。

        // // 回弹延时，默认 200ms，回弹到刷新高度所用时间
        // ptr.setDurationToClose(200);
        // // 头部回弹时间，默认 1000ms。
        // ptr.setDurationToCloseHeader(1000);
        // // 设置下拉达到高度后自动刷新（默认释放刷新）
        // ptr.setPullToRefresh(false);
        // // 刷新是否保持头部，默认值 true
        // ptr.setKeepHeaderWhenRefresh(true);
        // 自定义headerview
        if (enablePullRefresh()) {
            ptr.setRatioOfHeaderHeightToRefresh(1.2f);
            LedimListViewHeader header = new LedimListViewHeader(this);
            ptr.setHeaderView(header);
            ptr.addPtrUIHandler(header);
            ptr.setPtrHandler(new PtrHandler() {
                @Override
                public boolean checkCanDoRefresh(PtrFrameLayout ptrFrameLayout, View view,
                                                 View header) {
                    return PtrDefaultHandler.checkContentCanBePulledDown(ptrFrameLayout, mAdapterView, header);
                }

                @Override
                public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
                    pullRefresh();
                }
            });
        }
        return ptr;
    }

    protected boolean enablePullRefresh() {
        return true;
    }

    protected boolean enableLoadMoreRefresh() {
        return true;
    }
}
